package middleware

import (
	"context"
	"errors"

	"github.com/go-kit/kit/endpoint"
	pv "github.com/go-playground/validator/v10"
	"xincan.com.cn/tarot-go/internal/common/constants"
	"xincan.com.cn/tarot-go/internal/common/exception"
	"xincan.com.cn/tarot-go/internal/tarot"
)

// ValidationObjectMiddleware
// Title    		ValidationObjectMiddleware
// Description   	全局验证器: 适和结构体校验
// - 列子:
// - tarot.Validate.ValidationObject()(ep)
// Author      		alittlexincan@163.com         						2024/07/22 11:36
// Update  			alittlexincan@163.com         						2024/07/22 11:36
// Param    		ctx 					context.Context				上下文
// Return    		endpoint.Endpoint									返回经过验证处理的端点
func ValidationObjectMiddleware() endpoint.Middleware {
	return func(next endpoint.Endpoint) endpoint.Endpoint {
		return func(ctx context.Context, request interface{}) (interface{}, error) {
			if err := tarot.Validate.Validate.Struct(request); err != nil {
				//var errs validator.ValidationErrors
				var errs pv.ValidationErrors
				if ok := errors.As(err, &errs); ok {
					for _, err := range errs {
						return nil, exception.BusinessExceptionBuilder().
							WithCode(constants.ErrInvalidParam.Code()).
							WithMessage(constants.ErrInvalidParam.Message() + ": " + err.Translate(*tarot.Validate.Trans)).
							WithError(err)
					}
				}
			}
			return next(ctx, request)
		}
	}
}

// ValidationAttribute
// Title    		ValidationAttribute
// Description   	全局验证器: 适和属性校验
// - 例子:
// - tarot.Validate.ValidationAttribute("密码", password, "min=6,max=20,v-password")
// Author      		alittlexincan@163.com         						2024/07/22 11:36
// Update  			alittlexincan@163.com         						2024/07/22 11:36
// Param    		ctx 					context.Context				上下文
// Param    		label 						string					单个属性
// Param    		value 						string					属性对应值
// Param    		valid 						string					验证规则
// Return    		error												返回经过验证处理的端点
func ValidationAttribute(ctx context.Context, label string, value interface{}, rule string) error {
	err := tarot.Validate.Validate.Var(value, rule)
	if err != nil {
		for _, err := range err.(pv.ValidationErrors) {
			return exception.BusinessExceptionBuilder().
				WithCode(constants.ErrInvalidParam.Code()).
				WithMessage(constants.ErrInvalidParam.Message() + ": " + label + err.Translate(*tarot.Validate.Trans)).
				WithError(err)
		}
	}
	return nil
}
